// hangman.cpp -- some string methods
//#include <iostream>
//#include <string>
//#include <cstdlib>
//#include <ctime>
//#include <cctype>
//
//using std::string;
//const int NUM = 26;
//const string wordlist[NUM] = {
//	"apiary", "beetle", "cereal",
//	"danger", "ensign", "florid",
//	"garage", "health", "insult",
//	"jackal", "keeper", "loaner",
//	"manager", "nonce", "onset",
//	"plaid", "quilt", "remote",
//	"stolid", "train", "useful",
//	"volid", "whence", "xenon",
//	"yearn", "zippy"
//};
//
//int main()
//{
//	using std::cout;
//	using std::cin;
//	using std::tolower;
//	using std::endl;
//	std::srand(std::time(0));
//	char play;
//	cout << "Will you play a word game? <y/n> ";
//	cin >> play;
//	play = tolower(play);
//	while (play == 'y')
//	{
//		string target = wordlist[std::rand() % NUM];
//		int length = target.length();
//		string attempt(length, '-');
//		string badchars;
//		int guesses = 6;
//		cout << "Guess my secret word. It has " << length
//			<< " letters, and you guess\n"
//			<< "one letter at a time. Your get " << guesses
//			<< " wrong guesses.\n";
//		cout << "Your word: " << attempt << endl;
//		while (guesses > 0 && attempt != target)
//		{
//			char letter;
//			cout << "Guess a letter: ";
//			cin >> letter;
//			if (badchars.find(letter) != string::npos
//				|| attempt.find(letter) != string::npos)
//			{
//				cout << "You already guessed that. Try again.\n";
//				continue;
//			}
//			int loc = target.find(letter);
//			if (loc == string::npos)
//			{
//				cout << "Oh, bad guess!\n";
//				--guesses;
//				badchars += letter;	// add to string
//			}
//			else
//			{
//				cout << "Good guess!\n";
//				attempt[loc] = letter;
//				// check if letter appears again
//				loc = target.find(letter, loc + 1);
//				while (loc != string::npos)
//				{
//					attempt[loc] = letter;
//					loc = target.find(letter, loc + 1);
//				}
//			}
//			cout << "Your word: " << attempt << endl;
//			if (attempt != target)
//			{
//				if (badchars.length() > 0)
//				{
//					cout << "Bad choices: " << badchars << endl;
//				}
//				cout << guesses << " bad guesses left\n";
//			}
//		}
//		if (guesses > 0)
//		{
//			cout << "That's right!\n";
//		}
//		else
//		{
//			cout << "Sorry, the word is " << target << ".\n";
//		}
//		cout << "Will you play another? <y/n> ";
//		cin >> play;
//		play = tolower(play);
//	}
//
//	cout << "Bye\n";
//
//	return 0;
//}

// smrtptrs.cpp -- using three kinds of smart pointers
// requires support of C++11 shared_ptr and unique_ptr
//#include <iostream>
//#include <string>
//#include <memory>
//
//class Report
//{
//private:
//	std::string str;
//public:
//	Report(const std::string s) :str(s)
//	{
//		std::cout << "Object created!\n";
//	}
//	~Report() { std::cout << "Object deleted!\n"; }
//	void comment() const { std::cout << str << "\n"; }
//};
//
//int main()
//{
//	{
//		std::auto_ptr<Report> ps(new Report("using auto_ptr"));
//		ps->comment();	// use -> to invoke a member function
//	}
//	{
//		std::shared_ptr<Report> ps(new Report("using shared_ptr"));
//		ps->comment();
//	}
//	{
//		std::unique_ptr<Report> ps(new Report("using unique_ptr"));
//		ps->comment();
//	}
//
//	return 0;
//}

// vect3.cpp -- using STL functions
//#include <iostream>
//#include <string>
//#include <vector>
//#include <algorithm>
//
//struct Review
//{
//	std::string title;
//	int rating;
//};
//
//bool operator<(const Review& r1, const Review& r2);
//bool worseThan(const Review& r1, const Review& r2);
//bool FillReview(Review& rr);
//void ShowReview(const Review& rr);
//
//int main()
//{
//	using namespace std;
//
//	vector<Review> books;
//	Review temp;
//	while (FillReview(temp))
//	{
//		books.push_back(temp);
//	}
//	if (books.size() > 0)
//	{
//		cout << "Thank you. You entered the following "
//			<< books.size() << " ratings:\n"
//			<< "Rating\tBook\n";
//		for_each(books.begin(), books.end(), ShowReview);
//
//		sort(books.begin(), books.end());
//		cout << "Sorted by title:\nRating\tBook\n";
//		for_each(books.begin(), books.end(), ShowReview);
//		
//		sort(books.begin(), books.end(), worseThan);
//		cout << "Sorted by rating:\nRating\tBook\n";
//		for_each(books.begin(), books.end(), ShowReview);
//
//		random_shuffle(books.begin(), books.end());
//		cout << "After shuffling:\nRating\tBook\n";
//		for_each(books.begin(), books.end(), ShowReview);
//	}
//	else
//	{
//		cout << "No entries. ";
//	}
//	cout << "Bye.\n";
//
//	return 0;
//}
//
//bool operator<(const Review& r1, const Review& r2)
//{
//	if (r1.title < r2.title)
//	{
//		return true;
//	}
//	else if (r1.title == r2.title && r1.rating < r2.rating)
//	{
//		return true;
//	}
//	else
//	{
//		return false;
//	}
//}
//
//bool worseThan(const Review& r1, const Review& r2)
//{
//	if (r1.rating < r2.rating)
//	{
//		return true;
//	}
//	else
//	{
//		return false;
//	}
//}
//
//bool FillReview(Review& rr)
//{
//	std::cout << "Enter book title (quit to quit): ";
//	std::getline(std::cin, rr.title);
//	if (rr.title == "quit")
//	{
//		return false;
//	}
//	std::cout << "Enter book rating: ";
//	std::cin >> rr.rating;
//	if (!std::cin)
//	{
//		return false;
//	}
//	// get rid of rest of input line
//	while (std::cin.get() != '\n')
//	{
//		continue;
//	}
//	return true;
//}
//
//void ShowReview(const Review& rr)
//{
//	std::cout << rr.rating << "\t" << rr.title << std::endl;
//}

// copyit.cpp -- copy() and iterators
//#include <iostream>
//#include <iterator>
//#include <vector>
//
//int main()
//{
//	using namespace std;
//
//	int casts[10] = { 6,7,2,9,4,11,8,7,10,5 };
//	vector<int> dice(10);
//	// copy from array to vector
//	copy(casts, casts + 10, dice.begin());
//	cout << "Let the dice be cast!\n";
//	// create an ostream iterator
//	ostream_iterator<int, char> out_iter(cout, " ");
//	// copy from vector to output
//	copy(dice.begin(), dice.end(), out_iter);
//	cout << endl;
//	cout << "Implicit use of reverse iterator.\n";
//	copy(dice.rbegin(), dice.rend(), out_iter);
//	cout << endl;
//	cout << "Explicit use of reverse iterator.\n";
//	vector<int>::reverse_iterator ri;
//	for (ri = dice.rbegin(); ri != dice.rend(); ++ri)
//	{
//		cout << *ri << ' ';
//	}
//	cout << endl;
//
//	return 0;
//}

// inserts.cpp -- copy() and insert iterators
//#include <iostream>
//#include <string>
//#include <iterator>
//#include <vector>
//#include <algorithm>
//
//void output(const std::string& s)
//{
//	std::cout << s << " ";
//}
//
//int main()
//{
//	using namespace std;
//	string s1[4] = { "fine", "fish", "fashion", "false" };
//	string s2[2] = { "busy", "bats" };
//	string s3[2] = { "silly", "singers" };
//	vector<string> words(4);
//	copy(s1, s1 + 4, words.begin());
//	for_each(words.begin(), words.end(), output);
//	cout << endl;
//
//// construct anonymous back_insert_iterator object
//	copy(s2, s2 + 2, back_insert_iterator< vector<string> >(words));
//	for_each(words.begin(), words.end(), output);
//	cout << endl;
//
//// construct anonymous insert_iterator object
//	copy(s3, s3 + 2, insert_iterator< vector<string> >(words, words.begin()));
//	for_each(words.begin(), words.end(), output);
//	cout << endl;
//
//	return 0;
//}

// list.cpp -- using a list
//#include <iostream>
//#include <list>
//#include <iterator>
//#include <algorithm>
//
//void outint(int n) { std::cout << n << " "; }
//
//int main()
//{
//	using namespace std;
//	list<int> one(5, 2);	// list of 5 2s
//	int stuff[5] = { 1, 2, 4, 8, 6 };
//	list<int> two;
//	two.insert(two.begin(), stuff, stuff + 5);
//	int more[6] = { 6, 4, 2, 4, 6, 5 };
//	list<int> three(two);
//	three.insert(three.end(), more, more + 6);
//
//	cout << "List one: ";
//	for_each(one.begin(), one.end(), outint);
//
//	cout << endl << "List two: ";
//	for (auto x : two)
//	{
//		outint(x);
//	}
//
//	cout << endl << "List three: ";
//	for_each(three.begin(), three.end(), outint);
//
//	three.remove(2);
//	cout << endl << "List three minus 2s: ";
//	for_each(three.begin(), three.end(), outint);
//
//	three.splice(three.begin(), one);
//	cout << endl << "List three after splice: ";
//	for_each(three.begin(), three.end(), outint);
//
//	cout << endl << "List one: ";
//	for_each(one.begin(), one.end(), outint);
//
//	three.unique();
//	cout << endl << "List three after unique: ";
//	for_each(three.begin(), three.end(), outint);
//
//	three.sort();
//	three.unique();
//	cout << endl << "List three after sort & unique: ";
//	for_each(three.begin(), three.end(), outint);
//
//	two.sort();
//	three.merge(two);
//	cout << endl << "Sorted two merged into three: ";
//	for_each(three.begin(), three.end(), outint);
//	cout << endl;
//
//	return 0;
//}